<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/9/15
 * Time: 10:10
 */

namespace app\index\controller;


use app\common\controller\PayBase;
use app\index\model\ChongzhiList;
use think\Db;
use think\Exception;

class Payfsd extends PayBase{

    protected $merchantId;
    protected $key;
    protected $pay_url;
    protected $back_url;
    protected $href_url;

    public function __construct(){
        parent::__construct();
        $this->merchantId = '100002';
        $this->key = '6550f33367456220cdb32f84fc752ce7ff6e6925';
        $this->pay_url = 'http://pay.fsdpay.com/Api/Pay/payFor';
        $this->back_url = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].'/index/Payfsd/callBack';
        $this->href_url = $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].'/index/Payfsd/hrefUrl';
    }
    public function initPay($username='',$pay_type='',$amount=-1,$from=0){

        //接收数据
        $user = cookie('username','');
        $password = cookie('password','');
        $username =  empty($username) ? input('post.username','') : $username;
        $pay_type = empty($pay_type) ? input('post.pay_type','') : $pay_type;
        $amount = -1==$amount ? input('post.amount',0) : $amount;

        if ($pay_type == 'null' || $pay_type == '') return packJson('', '请选择支付方式', 500);
        $pay_method = Db::name('pay_type_list')
            ->alias("a")
            ->join('__PAY_METHOD__ b','a.method_id=b.id','LEFT')
            ->where(['a.method'=>19,'a.type_value'=>$pay_type])
            ->field('a.type_name,b.name,b.id,b.method,b.money')->find();
        $remark = $pay_method['type_name'].'-'.$pay_method['name'];

        //验证用户信息
        if( 0==$from ){
            if(!$user || !$username || ($user!=$username)) return packJson('','用户身份验证失败',500);
            $user_info = Db::name('username')->field('id,us_class,swzh,nbzh')->where(['username'=>$username,'password'=>$password])->find();
        }else{
            $user_info = Db::name('username')->field('id,us_class,swzh,nbzh')->where(['username'=>$username])->find();
        }

        if (!$user_info) return packJson('', '用户身份验证失败', 500);
        if ($user_info['swzh'] == 1) return packJson('', '试玩账号无法充值', 500);
        if ($user_info['nbzh'] == 1) return packJson('', '内部账号不支持线上充值', 500);

        //充值防骚扰是否开启，并进行处理
        $harassment = Db::name('xt_czfsr')->find();
        $now_time = time();
        if ($harassment['open'] > 0) {
            $nowys = $now_time - $harassment['time_xs'] * 60;
            $old_czjl = Db::name('chongzhi_list')->where('username', $username)->where('cztime', '>', $nowys)->find();
            if ($old_czjl['id'] > 0) {
                return packJson('', "系统充值防骚扰已开启，{$harassment['time_xs']}分钟内只能充值1次！", 500);
            }
        }

        //验证金额
//        if ($amount <= 0) return packJson('', '请输入充值金额', 500);
//        if ($amount < 10) return packJson('', '最低充值金额为十元人民币', 500);
//        if ($amount > 5000) return packJson('', '充值金额超过范围', 500);

        //计算优惠金额
        $msje = $msbs = 0;
        $cz_set = Db::name('xt_chongzhi')->find();
        $user_class = Db::name('us_class')->where('id', $user_info['us_class'])->find();
        $zsje = $amount * $user_class['czzsbl'] / 100;
        $zsbs = $user_class['czzsbl'];
        if ($amount >= $cz_set['xscz_je']) {
            $msje = $amount * $cz_set['xscz_zs'] / 100;
            $msbs = $cz_set['xscz_zs'];
        }
        //充值方案赠送
        $method_money = 0.00;
        if( floatval( $pay_method['money'] ) > 0 ){
            if( 0==intval( $pay_method['method'] ) ){
                //金额
                $method_money = $pay_method['money'];
            }else{
                //比例
                $method_money = floatval($amount) * floatval($pay_method['money']) / 100;
            }
        }
        $method_money = sprintf("%.2f",substr(sprintf("%.3f", $method_money), 0, -2));

        //生成订单号
        $order_sn = 'FSD' . str_pad($user_info['id'], 5, '0', STR_PAD_LEFT) . rand(1111, 9999);
        //组装数据
       $strs = "notify_url=".$this->back_url."&order_id=".$order_sn."&order_name=飞速达支付&price=".$amount."&return_url=".$this->href_url."&token=".$this->key."&type=".$pay_type."&uid=".$this->merchantId;
        $keys = md5($strs);

        if( 1==$from ) $this->href_url.="Third";

        
        

        // 构造要请求的参数数组
        $parameter = [
            "uid" => $this->merchantId,
            "price" => $amount,
            "type" => $pay_type,
            "notify_url" => $this->back_url,
            "return_url" => $this->href_url,
            "order_id" => $order_sn,
            "order_uid" => $username,
            "order_name" => "飞速达支付",
            "key"=>$keys,
        ];
      
        /*if (!is_numeric($pay_type)) {
            $parameter['payMethod'] = '915';
            $parameter['defaultBank'] = $pay_type;
        }else{
            $parameter['payMethod'] = $pay_type;
            $parameter['defaultBank'] = '';
        }*/
        //商户配置参数
        $allscore_config = [
            'merchantId' => $this->merchantId,
            'key'        => $this->key //入款的密钥 从商户后台入款API接口中获取
        ];
        $model = new ChongzhiList();
        $u = Db::name('username')->where('username',$username)->value('je');
        if( $model->setTransRechargeInfo($order_sn, $amount, $username, 0, 0, 1, $remark, $now_time, '飞速达支付', '系统自动', get_ip(), 0, $pay_type, $zsje, $zsbs, $msje, $msbs, $user_info['us_class'],'',0,$method_money,$u) ){
            //跳转支付页
            //待请求参数数组
            $url = self::buildForm($parameter, $this->pay_url, "POST" ,"提交", $allscore_config);
         
            return packJson( htmlentities($url) ,'',201);
        }else{
            return packJson('',"订单生产错误",500);
        }
    }
    public function callBack(){
        file_put_contents('fsd_back.txt',var_export(input(),true).PHP_EOL,FILE_APPEND);
        $param = input();
        $sign = input("Sign",'');
        $code = $_POST['code'];    // 0000为支付成功
        $order_id = $_POST['order_id'];  //传入的订单号
        $order_uid = $_POST['order_uid']; //传入的order_uid
        $price = $_POST['price'];   //支付金额
        $transaction_id = $_POST['transaction_id'];   //渠道流水号
        $token = "6550f33367456220cdb32f84fc752ce7ff6e6925"; 
        if ($code == '0000') {
            //验证是否是安全
        $str = 'order_id=' . $order_id . '&order_uid=' . $order_uid . '&price=' . $price . '&transaction_id=' . $transaction_id . '&token=' . $token;
        $key = md5($str);
        $rekey = $_POST['key'];
        if ($key == $rekey) {
            //此处处理您自己的业务
                $on_money = $price;
                $on_order_no = $transaction_id;
                $off_order_no = $order_id;
                if( empty($on_order_no) || empty($off_order_no) ){
                    return 'error';
                }
                $order_info = Db::name('chongzhi_list')->where('ddbh',$off_order_no)->find();
                if( $order_info['je']!=$on_money ) return 'error';
                $user_info = Db::name('username')->where('username',$order_info['username'])->find();
                $dml_set = Db::name('xt_dmsz')->where('id',1)->find();
                $xtcz = Db::name('xt_chongzhi')->where('id',1)->find();
                if( $xtcz['dmopen'] == 1 ){
                    $dmls = ($order_info['hy_msje'] + $order_info['hy_zsje'] + $order_info['je']+ $order_info['method_money']) * $dml_set['xscz_dmbs'];
                }else{
                    $dmls = $order_info['je'] * $dml_set['xscz_dmbs'];
                }
                //充值后账户总金额
                $czhje = $order_info['hy_msje'] + $order_info['hy_zsje'] + $order_info['je'] + $user_info['je']+ $order_info['method_money'];
                //充值总金额
                $czzje = $order_info['je'] + $user_info['czzje'];
                //用户当前打码量
                $dml = $user_info['dml'] + $dmls;
                Db::startTrans();
                try {
                    $zt = model('ChongzhiList')->where(['ddbh'=>$off_order_no])->value('zt');
                    if( 1==intval($zt) ){
                        throw new Exception("该订单已经成功通知");
                    }
                    if( !model('ChongzhiList')->updateRechargeInfo($off_order_no,$on_order_no,1,$czhje,time()) ){
                        throw new Exception("更新订单信息错误");
                    }
                    if( !model('Username')->upUserXsczInfo($czhje,$dml,$czzje,$order_info['username']) ){
                        throw new Exception("更新用户金额错误");
                    }
                    $fav_money = $order_info['hy_msje']+$order_info['hy_zsje']+ $order_info['method_money'];

                    //满送金额，等级赠送金额，充值方案赠送金额
                    $extcj = array(
                        'username'=>$user_info['username'],
                        'user_class'=>$user_info['us_class'],
                        'fstime'=>time(),
                        'czadmin' => '系统赠送',
                    );
                    $cjhje = floatval($order_info['je']) + floatval($user_info['je']) + floatval($order_info['hy_msje']);
                    if( floatval($order_info['hy_msje']) > 0 ){
                        $extcj['beizhu'] = '系统赠送，充值满送金额';
                        $extcj['cjje'] = $order_info['hy_msje'];
                        $extcj['cjhje'] = $cjhje;
                        Db::name('caijin_list')->insert($extcj);
                    }
                    $cjhje += floatval($order_info['hy_zsje']);
                    if( floatval($order_info['hy_zsje']) > 0 ){
                        $extcj['beizhu'] = '系统赠送，充值等级赠送金额';
                        $extcj['cjje'] = $order_info['hy_zsje'];
                        $extcj['cjhje'] = $cjhje;
                        Db::name('caijin_list')->insert($extcj);
                    }
                    $cjhje += floatval($order_info['method_money']);
                    if( floatval($order_info['method_money']) > 0 ){
                        $extcj['beizhu'] = '系统赠送，充值方案赠送金额';
                        $extcj['cjje'] = $order_info['method_money'];
                        $extcj['cjhje'] = $cjhje;
                        Db::name('caijin_list')->insert($extcj);
                    }

                    Db::name('username')->where('username',$order_info['username'])->setInc('cz_num');
                    $data = array('username' =>$order_info['username'],'test'=>"您账户充值金额：{$order_info['je']}，赠送金额：{$fav_money}。已充值到账，请注意查收！",'xx_time'=>time(),'ifdq'=>0);
                    Db::name('xiaoxi')->data($data)->insert();
                    Db::commit();
                    
                    return 'ok';
                } catch (\Exception $e) {
                    Db::rollback();
                    
                    return 'error';
                }
           
        } 
}

        
        
        
    }
    public function hrefUrl(){
        $order_id = $_GET["order_id"];
        $this->buildHtml("充值成功,订单号:{$order_id}");

    }
    public function hrefUrlThird(){
       $order_id = $_GET["order_id"];
        $this->buildHtml("充值成功,订单号:{$order_id}",1);
    }
    /**
     * 构造提交表单HTML数据
     * @param $para_temp (请求参数数组)
     * @param $gateway (网关地址)
     * @param $method   (提交方式。两个值可选：post、get)
     * @param $button_name (确认按钮显示文字)
     * @param $allscore_config (提交表单HTML文本)
     * @return string
     */
    private static function buildForm($para_temp, $gateway, $method, $button_name, $allscore_config) {

        //待请求参数数组
        //$para = self::buildRequestPara($para_temp,$allscore_config);

        $sHtml = "<form id='allscoresubmit' name='allscoresubmit' action='".$gateway."' method='post'>";
        foreach($para_temp as $key=>$value){
            $sHtml.= "<input type='hidden' name='".$key."' value='".$value."'/>";
        }
        //submit按钮控件请不要含有name属性
        $sHtml = $sHtml."<input type='submit' value='".$button_name."' style='display:none;'></form>";
        $sHtml = $sHtml."<script>document.forms['allscoresubmit'].submit();</script>";
        return $sHtml;
    }
    
    
    /**
     * 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @param $para (需要拼接的数组)
     * return 拼接完成以后的字符串
     */
    private static function createLinkstring($para) {
        $arg  = "";
        while (list ($key, $val) = each ($para)) {
            $arg.=$key."=".$val."&";
        }
        //去掉最后一个&字符
        $arg = substr($arg,0,count($arg)-2);
        //如果存在转义字符，那么去掉转义
        if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}
        return $arg;
    }
    /**
     * 除去数组中的空值和签名参数
     * @param $para 签名参数组
     * return 去掉空值与签名参数后的新签名参数组
     */
    private static function paraFilter($para) {
        $para_filter = array();
        while (list ($key, $val) = each ($para)) {
            if($key == "sign" || $key == "signType" || $val == "")continue;
            else    $para_filter[$key] = $para[$key];
        }
        return $para_filter;
    }
    /**
     * 对数组排序
     * @param $para 排序前的数组
     * return 排序后的数组
     */
    private static function argSort($para) {
        ksort($para);
        reset($para);
        return $para;
    }
    /**
     * 生成签名结果
     * @param $sort_para 要签名的数组
     * @param $key 鼎付分配给商户的密钥
     * @param $sign_type 签名类型 默认值：MD5
     * return 签名结果字符串
     */
    private static function buildMysign($sort_para,$key) {
        //把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
        $prestr = self::createLinkstring($sort_para);
        //把拼接后的字符串再与安全校验码直接连接起来
        $prestr = $prestr.$key;
        $mysgin = self::signMD5($prestr);
        return $mysgin;
    }
    /**
     * 签名字符串
     * @param $prestr 需要签名的字符串
     * @param $signType 签名类型 默认值：MD5
     * return 签名结果
     */
    private static function signMD5($prestr) {
        $sign='';
        $sign = md5($prestr);
        return $sign;
    }
    /**
     * 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @param $para 需要拼接的数组
     * return 拼接完成以后的字符串
     */
    private static function createLinkEncode($para) {
        $arg  = "";
        while (list ($key, $val) = each ($para)) {
            $arg.=$key."=".urlencode($val)."&";
        }
        //去掉最后一个&字符
        $arg = substr($arg,0,count($arg)-2);
        //如果存在转义字符，那么去掉转义
        if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}
        return $arg;
    }
    /**
     * 实现多种字符编码方式
     * @param $input 需要编码的字符串
     * @param $_output_charset 输出的编码格式
     * @param $_input_charset 输入的编码格式
     * return 编码后的字符串
     */
    private static function charsetEncode($input,$_output_charset ,$_input_charset) {
        $output = "";
        if(!isset($_output_charset) )$_output_charset  = $_input_charset;
        if($_input_charset == $_output_charset || $input ==null ) {
            $output = $input;
        } elseif (function_exists("mb_convert_encoding")) {
            $output = mb_convert_encoding($input,$_output_charset,$_input_charset);
        } elseif(function_exists("iconv")) {
            $output = iconv($_input_charset,$_output_charset,$input);
        } else die("sorry, you have no libs support for charset change.");
        return $output;
    }

    /**
     * 实现多种字符解码方式
     * @param $input 需要解码的字符串
     * @param $_output_charset 输出的解码格式
     * @param $_input_charset 输入的解码格式
     * return 解码后的字符串
     */
    private static function charsetDecode($input,$_input_charset ,$_output_charset) {
        $output = "";
        if(!isset($_input_charset) )$_input_charset  = $_input_charset ;
        if($_input_charset == $_output_charset || $input ==null ) {
            $output = $input;
        } elseif (function_exists("mb_convert_encoding")) {
            $output = mb_convert_encoding($input,$_output_charset,$_input_charset);
        } elseif(function_exists("iconv")) {
            $output = iconv($_input_charset,$_output_charset,$input);
        } else die("sorry, you have no libs support for charset changes.");
        return $output;
    }
    /**
     * MD5验签
     * @param privateKeyStr 私钥
     * @param data 加密字符串
     * @return String 密文数据
     */
    private static function verifySign($para_temp , $sign , $key){
        //除去待签名参数数组中的空值和签名参数
        $para_filter = self::paraFilter($para_temp);
        //对待签名参数数组排序
        $para_sort = self::argSort($para_filter);
        //生成签名结果
        $mysign = self::buildMysign($para_sort, $key);
        if ($mysign == $sign) {
            return true;
        } else {
            return false;
        }
    }
    private function curl_post_https($url,$data){ // 模拟提交数据函数
        $post_string = http_build_query($data);
        $options = array(
            'http' => array(
                'method' => 'POST',
                'header' => 'Content-type:application/x-www-form-urlencoded',
                'content' => $post_string,
                'timeout' => 15 * 60 // 超时时间
            )
        );
        $context = stream_context_create($options);
        $result = file_get_contents($url, false, $context);
        return $result;
    }
}












